package com.intretech.tj.live

import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import com.intretech.tj.global.tools.JSONTool
import com.intretech.tj.live.entity.DTO.LiveRequest
import com.intretech.tj.live.entity.DTO.LiveStatus
import com.intretech.tj.live.entity.DTO.PathRequest
import com.intretech.tj.live.entity.DTO.VehicleStatus
import com.intretech.tj.live.strategy.LiveStrategyFactory
import com.intretech.tj.mqtt.MQTTVerticle
import com.intretech.tj.mqtt.trigger.TopicMessageTrigger
import io.quarkus.scheduler.Scheduled
import io.smallrye.mutiny.vertx.core.AbstractVerticle
import io.vertx.core.Promise
import jakarta.enterprise.context.ApplicationScoped
import jakarta.inject.Inject
import org.slf4j.LoggerFactory
import tj.ums.com.intretech.tj.live.service.LiveService
import java.nio.charset.StandardCharsets


/**
 * Live服务的Verticle实现
 * 负责处理演示以及调度场景
 */
@ApplicationScoped
class LiveVerticle @Inject constructor(
    private val liveService: LiveService,
    private val mqttVerticle: MQTTVerticle, // MQTT消息发布服务
    private val topicMessageTrigger: TopicMessageTrigger, // MQTT消息订阅服务
    private val config: LiveConfig,
    private val livePublicVerticle: LivePublicVerticle, // 公共消息发布服务
    private val liveStrategyFactory: LiveStrategyFactory // 沙盘模式策略工厂
) : AbstractVerticle() {

    private val logger = LoggerFactory.getLogger(LiveVerticle::class.java)

    @Volatile
    private var runtimeLiveId = -1

    @Volatile
    private var runtimeLiveNode = -1

    /**
     * Verticle启动时执行的初始化方法
     */
    override fun start(startPromise: Promise<Void>?) {


        registerLive0Handler()
        registerLiveAHandler()
        registerLiveBHandler()
        registerLiveCHandler()
        // 接收并存储车辆信息
        registerVehicleStatusHandler()

        // 发送车辆初始化请求
    }

    /**
     * 发送当前正在运行的情景和点位
     */
    @Scheduled(every = "1s")
    fun sendLiveStatus() {
        var liveType = ""
        when (runtimeLiveId) {
            0 -> liveType = "live0"
            1 -> liveType = "liveA"
            2 -> liveType = "liveB"
            3 -> liveType = "liveC"
        }
        val liveStatus = LiveStatus(runtimeLiveNode, liveType)
        mqttVerticle.publish("service/live/status", 0, JSONTool.toJSONString(liveStatus))
    }


    /**
     * 注册车辆状态处理器
     * 存储车辆信息
     */
    private fun registerVehicleStatusHandler() {
        topicMessageTrigger.setTrigger(
            config.vehicleStatusTopic(),
            logger.name
        ) { idAndMessage: TopicMessageTrigger.IDAndMessage ->
            // 解析车辆状态消息
            try {
                val vehicleState = Gson().fromJson(
                    idAndMessage.message().payload().toString(StandardCharsets.UTF_8),
                    VehicleStatus::class.java
                )

                val currentNodeChange = liveService.updateVehicleStates(vehicleState)
                logger.info("更新车辆信息成功,车辆ID:${vehicleState.vehicleId}")

                // 当前位置是否发生了改变
                if (currentNodeChange) {
                    // 根据不同 LiveId 的获得特定的策略
                    val liveStrategy = liveStrategyFactory.get(runtimeLiveId)
                    val request = liveStrategy.handle(vehicleState)
                    // 是否需要更新车辆的起点终点
                    if (request != null) {
                        // 更新 车辆 将要前往的 地点
                        registerVehicleInitHandler(request.vehicleId, request.endNodeId)
                    }


                }
                //logger.warn("接收到错误的请求")
            } catch (e: Exception) {
                logger.error("解析Live请求JSON失败", e)
            }
        }
    }


    private fun registerLive0Handler() {
        topicMessageTrigger.setTrigger(
            "service/live/live0", logger.name
        ) { idAndMessage: TopicMessageTrigger.IDAndMessage ->
            val liveRequest = JSONTool.parseObject(
                idAndMessage.message().payload().toString(StandardCharsets.UTF_8),
                LiveRequest::class.java
            )

            try {
                if (liveRequest.liveNode == 0) {
                    if (runtimeLiveId == -1) {
                        runtimeLiveId = 0
                        runtimeLiveNode = 0
                    } else {
                        logger.error("车辆正在运行其他情景")
                    }
                } else {
                    logger.warn("接收到错误的请求")
                }
            } catch (e: JsonSyntaxException) {
                // JSON 解析异常
                logger.error("解析Live0 请求JSON失败", e)
            }
        }
    }

    private fun registerLiveAHandler() {
        topicMessageTrigger.setTrigger(
            "service/live/liveA", logger.name
        ) { idAndMessage: TopicMessageTrigger.IDAndMessage ->
            val liveRequest = JSONTool.parseObject(
                idAndMessage.message().payload().toString(StandardCharsets.UTF_8),
                LiveRequest::class.java
            )

            try {
                if (runtimeLiveId == -1 || runtimeLiveId == 0) {
                    runtimeLiveId = 1
                    runtimeLiveNode = liveRequest.liveNode
                } else {
                    logger.error("车辆正在运行其他情景 liveA")
                }
            } catch (e: JsonSyntaxException) {
                logger.error("解析liveA JSON失败", e)
            }
        }
    }

    private fun registerLiveBHandler() {
        topicMessageTrigger.setTrigger(
            "service/live/liveB", logger.name
        ) { idAndMessage: TopicMessageTrigger.IDAndMessage ->
            val liveRequest = JSONTool.parseObject(
                idAndMessage.message().payload().toString(StandardCharsets.UTF_8),
                LiveRequest::class.java
            )

            try {
                if (runtimeLiveId == -1 || runtimeLiveId == 0) {
                    runtimeLiveId = 2
                    runtimeLiveNode = liveRequest.liveNode
                } else {
                    logger.error("车辆正在运行其他情景 liveB")
                }
            } catch (e: JsonSyntaxException) {
                logger.error("解析liveB JSON失败", e)
            }
        }
    }

    private fun registerLiveCHandler() {
        topicMessageTrigger.setTrigger(
            "service/live/liveC", logger.name
        ) { idAndMessage: TopicMessageTrigger.IDAndMessage ->
            val liveRequest = JSONTool.parseObject(
                idAndMessage.message().payload().toString(StandardCharsets.UTF_8),
                LiveRequest::class.java
            )

            try {
                if (runtimeLiveId == -1 || runtimeLiveId == 0) {
                    runtimeLiveId = 3
                    runtimeLiveNode = liveRequest.liveNode
                } else {
                    logger.error("车辆正在运行其他情景 liveC")
                }
            } catch (e: JsonSyntaxException) {
                // JSON 解析异常
                logger.error("解析liveC JSON失败", e)
            }
        }
    }

    /**
     * 发送车辆初始化请求
     * TODO 完善发送信息
     */
    private fun registerVehicleInitHandler(vehicleId: String, endNodeId: Int) {

        // 1. 得到全部在线车辆 id 信息
        val vehicleCurrentId = liveService.getVehicleCurrentNodeId(vehicleId)

        // 2. TODO 根据不同的 车辆id 封装不同的初始化请求
        val pathRequest = PathRequest(vehicleId, vehicleCurrentId, endNodeId, System.currentTimeMillis().toString())

        // 3. 发送车辆初始化信息
        mqttVerticle.publish(
            "service/gpp/getNewPath",
            0,
            JSONTool.toJSONString(pathRequest)
        )
    }
}